

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <unistd.h>

#include <iostream>
#include <cstring>

int main() {

    int sockfd = socket(AF_INET, SOCK_STREAM, 0);

    struct sockaddr_in serveraddr;
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(10224);
    serveraddr.sin_addr.s_addr = INADDR_ANY;

    bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));

    listen(sockfd, 20);
    struct sockaddr_in cliaddr;
    socklen_t len = sizeof(struct sockaddr);
    int clifd;
    // int clifd = accept(sockfd, (struct sockaddr *)&cliaddr, &len);
    // std::cout << "accept: " << clifd << std::endl;

    char buf[1024];


    int epfd = epoll_create(10);
    epoll_event event;
    event.events = EPOLLIN;
    event.data.fd = sockfd;
    epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &event);
    epoll_event events[100];
    while (true) {

        int nready = epoll_wait(epfd, events, 100, -1);
        for (int i = 0; i < nready; i++) {
            if (events[i].data.fd == sockfd) {
                clifd = accept(sockfd, (struct sockaddr *)&cliaddr, &len);
                std::cout << "accept: " << clifd << std::endl;
                event.events = EPOLLIN;
                event.data.fd = clifd;
                epoll_ctl(epfd, EPOLL_CTL_ADD, clifd, &event);
            } else if (events[i].events & EPOLLIN) {
                clifd = events[i].data.fd;
                int ret = recv(clifd, buf, 1024, 0);
                if (ret == 0) {
                    event.events = EPOLLIN;
                    event.data.fd = clifd;
                    epoll_ctl(epfd, EPOLL_CTL_DEL, clifd, &event);
                    close(clifd);
                    std::cout << "clifd: " << clifd << " close\n";
                } else if (ret > 0) {
                    std::cout << buf << std::endl;
                    ret = send(clifd, buf, strlen(buf), 0);
                    if (ret == -1) {
                        close(clifd);
                    }
                }
            }
        }
    }

    return 0;
}